use super::{
    err, err_value, json, ok, throw_err, Base, Client, ECode, KeyNode, MapSv, Resp, SvCache, VBase,
    VMap, Value,
};

pub struct Node;

impl Base for Node {}

impl Node {
    pub async fn do_cmd(&self, para: &Value, cmd: &str, client: &Client) -> Resp {
        let data = para.ckobj()?;

        match cmd {
            "show" => {
                let k_sn = self.get_key(data)?;
                let body = client.get(&k_sn)?;
                ok!(body)
            }
            _ => throw_err!(ECode::NoServe, "no node serve"),
        }
    }

    pub async fn do_cache(&self, para: &Value, cmd: &str, cache: SvCache) -> Resp {
        let data = para.ckobj()?;

        match cmd {
            "clear" => {
                cache.invalidate_all();
                ok!()
            }
            "show" => {
                let k_sn = self.get_key(data)?;
                match cache.get(&k_sn) {
                    Some(v) => ok!(v),
                    None => err!(ECode::Cache, "value not found"),
                }
            }
            _ => throw_err!(ECode::NoServe, "no node cache serve"),
        }
    }

    fn get_key(&self, data: &MapSv) -> Result<String, Value> {
        let line = data.ck_str("line")?;
        let tp = data.ck_str("tp")?;
        let sub = data.k_str("sub");
        let ext = data.k_str("ext");
        let sn = match data.k_str("sn") {
            Some(v) => v,
            None => "",
        };

        self.key_value(line, tp, sub, sn, ext)
    }
}

impl KeyNode for Node {
    fn key_run(&self, _model: &str) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }

    fn key_pause(&self, _model: &str) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }

    fn key_all(&self, _model: &str) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }

    fn key_sn(&self, _model: &str, _sn: &str) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }

    fn key_sn_ext(&self, _model: &str, _sn: &str, _ext: &str) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }

    fn key_sub_sn(&self, _model: &str, _sub: &str, _sn: &str) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }

    fn key_sub_sn_ext(
        &self,
        _model: &str,
        _sub: &str,
        _sn: &str,
        _ext: &str,
    ) -> Result<String, Value> {
        err!(ECode::Cache, "value not found")
    }
}
